<?php
include_once 'CtFile.class.php';
include_once 'pclzip.lib.php';
/**
 * 处理压缩文件的类
 * 1 所有的同组压缩文件需要在同一目录中
 * 2 使用非扩展解压rar的时候出现严重乱码，暂时只能使用rar扩展方式，切不能够使用是否加密
 * 支持的文件类型
 * rar                 支持
 * zip                 支持
 * 7z                  不支持
 * tar                 不支持
 * tar.gz              不支持
 * tar.bz2             不支持
 * 其他压缩文件        不支持
 * @author chengtao<chengtao05011633@gmial.com>
 * @version 0.0.2 开发版
 */
class CtUnCompress{
	/**
	 * 配置
	 */
	private $prior_ext = true;
	private $rar_cmd = '/usr/local/bin/unrar x -o- -y "{in_file}"  "{out_dir}"';
	private $zip_cmd = '/usr/bin/unzip "{in_file}" -d  "{out_dir}"';
	private $seven7_cmd = '/usr/local/bin/7za e "{in_file}" -o"{out_dir}" -y ';
	private $sopport_file = array('rar','zip');
	private $compress_file_list = array();        //元素为CtFile对象
	
	/**
	 * 文件类型列表
	 */
	private $compress_mime_list = array(
		//zip文件
		'zip'=>array(
			"application/zip",
			"application/x-zip",
			"application/x-zip-compressed",
		),
		//rar文件
		'rar'=>array(
			'application/x-rar'
		),
		//7z文件
		'servenz'=>array(),
	);
	/**
	 * 添加压缩文件，如果是分卷则多次添加
	 */
	public function addFile($file){
		$this->compress_file_list[] = $file;
	}
	/**
	 * 清空压缩文件文件列表，使用此对象用于下一组文件解压
	 */
	public function clearFile(){
		$this->compress_file_list = array();
	}
	/**
	 * 是否是是压缩文件,组内的所有文件文件类型必须相同
	 */
	private function getCompressFileType(){
		$mime_list = array();
		foreach($this->compress_file_list as $v){
			$mime_list[] = $v->getMime();
		}
		$mime_list = array_unique($mime_list);
		if(count($mime_list)<>1){//保证文件类型必须一样
			return false;
		}
		$mime = $mime_list[0];
		foreach($this->compress_mime_list as $k=> $v){
			foreach($v as $v1){
				if($v1 == $mime){
					if($this->compress_file_list[0]->getExt() == $k){//对于非 /\.part\d+\.rar$/is 的分卷压缩直接pass
						return $k;
					}else{
						return false;
					}
				}
			}
		}
		if($this->compress_file_list[0]->getExt() == '7z'){
			return 'sevenZ';
		}
		return false;
	}
	/**
	 * @param $to_dir 解压之后的文件保存的路径
	 * @param $del_source 是否删除压缩文件 默认不删除
	 */
	public function unCompress($out_dir,$del_source = false){
		$compress_type = $this->getCompressFileType();
		if($compress_type){
			$this->{$compress_type.'UnCompress'}($out_dir);
		}else{
			echo "These files are not compress file.\n";
		}
	}
	/**
	 * 删除本次解压的压缩文件
	 * @return 是否删除成功
	 */
	public function delSourceFile(){
		foreach($this->compress_file_list as $file){
			$file->delFile();
		}
		return true;
	}
	/**
	 * 解压缩zip文件
	 */
	private function zipUnCompress($out_dir){
		if($this->prior_ext && extension_loaded('zip')){
			$archive = new PclZip($this->compress_file_list[0]->getAbsolutePath()); 
			$archive->extract(PCLZIP_OPT_PATH,$out_dir);
		}else{
			$in_file = $this->compress_file_list[0]->getAbsolutePath();
			$exe = str_replace(array('{in_file}','{out_dir}'),array($in_file,$out_dir),$this->zip_cmd);
			$this->exe($exe);
		}
	}
	/**
	 * 解压缩rar文件
	 */
	private function rarUnCompress($out_dir){
		if($this->prior_ext && extension_loaded('rar')){
			$rar_file = rar_open($this->compress_file_list[0]->getAbsolutePath());
			if($rar_file){
				$list = rar_list($rar_file);
				foreach($list as $file) {
					$file_name =  $file->getName();
					$entry = rar_entry_get($rar_file,$file_name);
					$entry->extract($out_dir); 
				}
				rar_close($rar_file);
			}
		}else{
			$in_file = $this->compress_file_list[0]->getAbsolutePath();
			$exe = str_replace(array('{in_file}','{out_dir}'),array($in_file,$out_dir),$this->rar_cmd);
			$this->exe($exe);
		}
	}
	/**
	 * 解压缩7z文件
	 */
	private function sevenZUnCompress($out_dir){
		$in_file = $this->compress_file_list[0]->getAbsolutePath();
		$exe = str_replace(array('{in_file}','{out_dir}'),array($in_file,$out_dir),$this->seven7_cmd);
		$this->exe($exe);
	}
	/**
	 * 执行命令行命令
	 */
	private function exe($command){
		$out=array();
		exec($command,$out);
		return implode("\n",$out);
	}
	/**
	 * 返回最后一条错误信息
	 */
	public function getError(){
		return $this->error;
	}
}
?>